package com.aabte.auth.role.application;

import com.aabte.auth.role.domain.exception.RoleCannotDeleteException;
import com.aabte.auth.role.domain.exception.RoleNotExistException;
import com.aabte.auth.role.domain.model.Role;
import com.aabte.auth.role.domain.model.RoleId;
import com.aabte.auth.role.domain.model.RoleName;
import com.aabte.auth.role.domain.repository.RoleRepository;
import org.apache.commons.collections.CollectionUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.Optional;

@Service
public class RoleService {

    @Resource
    private RoleRepository roleRepository;

    @Transactional(rollbackFor = Exception.class)
    public RoleId create(RoleName roleName) {
        Role role = new Role(roleRepository.nextRoleId(), roleName);
        roleRepository.addOrUpdate(role);
        return role.getRoleId();
    }

    @Transactional(rollbackFor = Exception.class)
    public void disable(RoleId roleId) {
        Optional<Role> roleOptional = roleRepository.find(roleId);
        if (!roleOptional.isPresent()) {
            throw new RoleNotExistException("roleId: " + roleId.getId());
        }
        Role role = roleOptional.get();
        role.disable();
        roleRepository.remove(role);
    }

    @Transactional(rollbackFor = Exception.class)
    public boolean delete(RoleId roleId) {
        Optional<Role> roleOptional = roleRepository.find(roleId);
        if (!roleOptional.isPresent()) {
            throw new RoleNotExistException("roleId: " + roleId.getId());
        }

        Role role = roleOptional.get();
        if (canDelete(role)) {
            roleRepository.remove(role);
            return true;
        }
        throw new RoleCannotDeleteException("roleId: " + roleId.getId());
    }

    public Role role(RoleId roleId) {
        Optional<Role> roleOptional = roleRepository.find(roleId);
        if (roleOptional.isPresent()) {
            return roleOptional.get();
        }
        throw new RoleNotExistException("roleId: " + roleId.getId());
    }

    private boolean canDelete(Role role) {
        return CollectionUtils.isEmpty(role.getGroups());
    }
}
